const _ = require('lodash');
const DbService = require('./db2');
const { TABLE_NAME, knex } = require('../models');
const { objectConvertToCase } = require('../utils');
const BaseService = require('./base');

class UserService extends BaseService {
  constructor() {
    super();
    this.dbService = new DbService(TABLE_NAME.user);
  }

  async create(data) {
    // await this.dbService.hSet('user', data.userId, data);
    data.id = data.id || data.userId;
    await this.dbService.insert(data);
  }

  // 同步全部用户数据
  async batchSyncUserList(data, organizationId) {
    if (!organizationId) {
      throw new Error('缺少organizationId');
    }

    // 先查出来合并
    const oldAll = await this.dbService.selectAll({ organizationId });
    const keyMap = _.keyBy(oldAll, 'openId');

    // data 为大写开头的数字
    const newData = data.map(item => {
      const { Mobile, DisplayName, Verified, Roles, ...rest } = item;
      // 库存数据
      const oldItem = keyMap[item.OpenId];
      const fields = _.pick(rest, 'CreatedOn', 'Verified', 'VerifiedOn', 'QuiteJob');
      if (oldItem) {
        const newData = {
          ...fields,
          userId: oldItem.userId,
          openId: oldItem.openId,
          agentMobile: Mobile,
          agentName: DisplayName,
          verified: Verified,
          roles: Roles,
        };
          // 实名认证后，保留原来的不允许修改，原因：用户登录可能并不知道实名是哪一个手机号了
        return newData;
      }
      return {
        ...fields,
        id: item.OpenId,
        userId: item.OpenId,
        openId: item.OpenId,
        // 以下是经办人真实签署信息
        agentMobile: Mobile,
        agentName: DisplayName,
        // 以下两个是本系统登录使用
        mobile: Mobile,
        userName: DisplayName,
        organizationId,
        verified: Verified,
        roles: Roles,
      };
    });

    const promises = [];
    newData.map(async dbItem => {
      const data = objectConvertToCase(dbItem);
      if (dbItem.openId) {
        if (data.roles) {
          data.roles = JSON.stringify(data.roles);
        } else {
          delete data.roles;
        }
        if (data.createdOn && !Number.isNaN(data.createdOn)) {
          data.createdOn = new Date(data.createdOn * 1000);
        } else {
          delete data.createdOn;
        }
        if (data.verifiedOn && !Number.isNaN(data.verifiedOn)) {
          data.verifiedOn = new Date(data.verifiedOn * 1000);
        } else {
          delete data.verifiedOn;
        }
        if (keyMap[data.userId]) {
          promises.push(this.dbService.updateById(data.userId, data));
        } else {
          promises.push(this.dbService.insert(data));
        }
      }
    });
    return Promise.all(promises);
  }

  async findWithOrg(userId) {
    const result = await knex.select().from(TABLE_NAME.user)
      .where({ [`${TABLE_NAME.user}.id`]: userId })
      .innerJoin(TABLE_NAME.organization, `${TABLE_NAME.user}.organizationId`, `${TABLE_NAME.organization}.id`);
    return result[0];
  }

  async resolveToken(userId) {
    return this.findWithOrg(userId);
  }


  async list(where, offset, limit) {
    const userData = await this.dbService.selectBy({
      where,
      offset,
      limit,
    });
    return userData.map(user => {
      if (user.roles) {
        user.roles = JSON.parse(user.roles);
      }
      return user;
    });
  }

  async count(where) {
    return this.dbService.countAll(where);
  }
}

module.exports = UserService;
